/*
 *文件作用: 测试驱动
*/

#include <stdio.h>
#include "leptjson.h"

static int test_count = 0;  //总测试次数
static int test_pass = 0;  //测试通过次数
static int main_ret = 0;  //测试程序返回值，0 for success

//基本比较宏定义，用以比较预期结果和实际结果是否一致
#define EXPECT_EQ_BASE(equality, expect, actual, format) \
do { \
    test_count++; \
    if (equality) { \
        test_pass++; \
    } else {\
        fprintf(stderr, "%s:%d: expect: " format " actual: " format "\n", __FILE__, __LINE__, expect, actual ); \
        main_ret = 1; \
    }\
} while(0)

//比较预期结果和实际结果，指定以int作为格式化方式，基于基本比较宏
#define EXPECT_EQ_INT(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%d")

//*错误码测试宏，要求出现错误时能给出预期错误码，并将节点类型强制置为 LETP_NULL
#define TEST_ERROR(error, json) \
do { \
    lept_value v; \
    v.type = LEPT_FALSE; \
    EXPECT_EQ_INT(error, lept_parse(&v, json)); \
    EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v)); \
} while(0)

//一个尝试统一value解析测试, 但不知道符不符合规范的宏
// //value解析测试宏，以 LEPT_NULL 初始化节点类型，要求解析成功，并正确修改节点类型
// #define TEST_VALUE(expect_type, json) \
// do { \ 
//     lept_value v; \
//     v.type = NULL; \
//     EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, json)) \
//     EXPECT_EQ_INT(expect_type, lept_get_type(&v)) \
// } while()

//对null值解析的测试
static void test_parse_null() {
    lept_value v;
    v.type = LEPT_TRUE;
    EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "null"));
    EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v));
}

//测试解析true
static void test_parse_true() {
    lept_value v;
    v.type = LEPT_NULL;
    EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "true"));
    EXPECT_EQ_INT(LEPT_TRUE, lept_get_type(&v));
}

//测试解析false
static void test_parse_false() {
    lept_value v;
    v.type = LEPT_TRUE;
    EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(&v, "false"));
    EXPECT_EQ_INT(LEPT_FALSE, lept_get_type(&v));
}

// //测试多值输入
// static void test_parse_non_singular() {
//     lept_value v;
//     v.type = LEPT_TRUE;
//     EXPECT_EQ_INT(LEPT_PARSE_ROOT_NOT_SINGULAR, lept_parse(&v, "   false  a   "));
//     EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v));
// }

// //测试无值输入
// static void test_parse_expect_value() {
//     lept_value v;
//     v.type = LEPT_TRUE;
//     EXPECT_EQ_INT(LEPT_PARSE_EXPECT_VALUE, lept_parse(&v, " \t\n\r"));
//     EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v));
// }

// //测试非法输入
// static void test_parse_invalid_value() {
//     lept_value v;
//     v.type = LEPT_TRUE;
//     EXPECT_EQ_INT(LEPT_PARSE_INVALID_VALUE, lept_parse(&v, "123"));
//     EXPECT_EQ_INT(LEPT_NULL, lept_get_type(&v));
// }

//解析测试集合
static void test_parse() {
    test_parse_null();  //测试解析null值
    test_parse_true();  //测试解析true值
    test_parse_false();  //测试解析false值
    TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "false f");  //测试无值输入
    TEST_ERROR(LEPT_PARSE_EXPECT_VALUE, " \t\n\r");  //测试多值输入
    TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "monday");  //测试非法输入
}

int main(void) {
    test_parse();  //测试解析

    //打印通过次数、总测试次数、通过率
    printf("%d / %d (%3.2f%%) passed\n", test_pass, test_count, test_pass * 100.0 / test_count);
    return main_ret;
}